home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Video
/
World of Video.iso
/
gfxprograms
/
3dprograms
/
shelly
/
shelly.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-13
|
20KB
|
873 lines
/*****************************************************/
/* ShellyV1.2: The ShellShapeGenerator by: */
/* RANDi */
/* (rschultz@informatik.uni-rostock.de) */
/*****************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <memory.h>
#include "shelly.h"
int countw=0, counth=0, countp=0;
double camx=0,camy=500,camz=500;
/********************************************/
/*cot: */
/********************************************/
double cot(double in)
{
if (sin(in) == 0)
return(0);
else
return(cos(in)/sin(in));
}
/********************************************/
/*round: */
/********************************************/
double round(double in)
{
if((floor(in)-in) < 0)
return(floor(in));
else
return(floor(in)+1);
}
/********************************************/
/*myfree: */
/********************************************/
int myfree(struct punkt *anker1)
{
struct punkt *hp, *hpnew;
if (anker1 == NULL)
return(0);
hp = anker1;
hpnew = hp;
do
{
hp = hpnew;
hpnew = (*hp).next;
cfree(hp);
}
while(hpnew);
return(0);
}
/********************************************/
/*mycopystr: */
/********************************************/
char *mycopystr(char *source,char *destination,char endchar)
{
int ende = 1;
char *merk;
merk = destination; /* merk points now on destination */
while (ende)
{
if ((*source == '\0') || (*source == endchar))
{
ende = 0;
}
else
{
*destination = *source;
destination++;
source++;
} /* if */
} /* while */
*destination = '\0';
return(merk);
}
/********************************************/
/*ReadInfile: */
/********************************************/
void ReadInfile(struct ShellyArguments *ShellyArgs,char *fin)
{
char readline[laenge], hilf[laenge], *hp;
FILE *fp;
(*ShellyArgs).output = POV;
fp = fopen(fin,"r");
if (fp != NULL)
{
fprintf(stderr,"Parsing:");
while (fgets(readline,laenge,fp))
{
fprintf(stderr,".");
hp = strstr(readline,"alpha:");
if (hp != NULL)
{
mycopystr(hp+6,hilf,'\0');
(*ShellyArgs).alpha = atof(hilf);
} /* if */
hp = strstr(readline,"beta:");
if (hp != NULL)
{
mycopystr(hp+5,hilf,'\0');
(*ShellyArgs).beta = atof(hilf);
} /* if */
hp = strstr(readline,"phi:");
if (hp != NULL)
{
mycopystr(hp+4,hilf,'\0');
(*ShellyArgs).phi = atof(hilf);
} /* if */
hp = strstr(readline,"my:");
if (hp != NULL)
{
mycopystr(hp+3,hilf,'\0');
(*ShellyArgs).my = atof(hilf);
} /* if */
hp = strstr(readline,"omega:");
if (hp != NULL)
{
mycopystr(hp+6,hilf,'\0');
(*ShellyArgs).omega = atof(hilf);
} /* if */
hp = strstr(readline,"smin:");
if (hp != NULL)
{
mycopystr(hp+5,hilf,'\0');
(*ShellyArgs).smin = atof(hilf);
} /* if */
hp = strstr(readline,"smax:");
if (hp != NULL)
{
mycopystr(hp+5,hilf,'\0');
(*ShellyArgs).smax = atof(hilf);
} /* if */
hp = strstr(readline,"sd:");
if (hp != NULL)
{
mycopystr(hp+3,hilf,'\0');
(*ShellyArgs).sd = atof(hilf);
} /* if */
hp = strstr(readline,"A:");
if (hp != NULL)
{
mycopystr(hp+2,hilf,'\0');
(*ShellyArgs).A = atof(hilf);
} /* if */
hp = strstr(readline,"a:");
if (hp != NULL)
{
mycopystr(hp+2,hilf,'\0');
(*ShellyArgs).a = atof(hilf);
} /* if */
hp = strstr(readline,"b:");
if (hp != NULL)
{
mycopystr(hp+2,hilf,'\0');
(*ShellyArgs).b = atof(hilf);
} /* if */
hp = strstr(readline,"P:");
if (hp != NULL)
{
mycopystr(hp+2,hilf,'\0');
(*ShellyArgs).P = atof(hilf);
} /* if */
hp = strstr(readline,"W1:");
if (hp != NULL)
{
mycopystr(hp+3,hilf,'\0');
(*ShellyArgs).W1 = atof(hilf);
} /* if */
hp = strstr(readline,"W2:");
if (hp != NULL)
{
mycopystr(hp+3,hilf,'\0');
(*ShellyArgs).W2 = atof(hilf);
} /* if */
hp = strstr(readline,"N:");
if (hp != NULL)
{
mycopystr(hp+2,hilf,'\0');
(*ShellyArgs).N = atof(hilf);
} /* if */
hp = strstr(readline,"L:");
if (hp != NULL)
{
mycopystr(hp+2,hilf,'\0');
(*ShellyArgs).L = atof(hilf);
} /* if */
hp = strstr(readline,"omin:");
if (hp != NULL)
{
mycopystr(hp+5,hilf,'\0');
(*ShellyArgs).omin = atof(hilf);
} /* if */
hp = strstr(readline,"omax:");
if (hp != NULL)
{
mycopystr(hp+5,hilf,'\0');
(*ShellyArgs).omax = atof(hilf);
} /* if */
hp = strstr(readline,"od:");
if (hp != NULL)
{
mycopystr(hp+3,hilf,'\0');
(*ShellyArgs).od = atof(hilf);
} /* if */
hp = strstr(readline,"POV");
if (hp != NULL)
{
(*ShellyArgs).output = POV;
} /* if */
hp = strstr(readline,"RPL");
if (hp != NULL)
{
(*ShellyArgs).output = RPL;
} /* if */
hp = strstr(readline,"T3D");
if (hp != NULL)
{
(*ShellyArgs).output = T3D;
} /* if */
} /* while */
fprintf(stderr,"\n");
if (fclose(fp) != 0)
fprintf(stderr,"Error while closing file: %s!\n",fin);
}
else
{
fprintf(stderr,"Could not open datafile: %s!\n",fin);
exit(5);
}
} /* ReadInfile */
/********************************************/
/* writepovheader: reads in camera/light's */
/* */
/********************************************/
void writepovheader(FILE *fp)
{
fprintf(fp,"/* POV-Scenefile generated by Shelly1.2 */\n");
fprintf(fp,"/* by RANDi: (rschultz@informatik.uni-rostock.de) */\n");
fprintf(fp,"#declare te = pigment { color red 1 green 0 blue 0 }\n");
fprintf(fp,"camera\n{\n location <%.1f,%.1f,%.1f>\n",camx,camy,camz);
fprintf(fp," look_at <0, 0, 0>\n}\n");
fprintf(fp,"object\n{\n light_source {\n");
fprintf(fp," <250, 500, 500> color red 1 green 1 blue 1\n }\n");
fprintf(fp,"}\n");
fprintf(fp,"object\n{\n light_source {\n");
fprintf(fp," <-250, 500, 500> color red 1 green 1 blue 1\n }\n");
fprintf(fp,"}\n");
} /* writepovheader */
/********************************************/
/* writepovtriangles: */
/********************************************/
int writepovtriangles(FILE *fp,struct punkt *anker1,struct punkt *anker2)
{
struct punkt *p11, *p12, *p21, *p22;
if ((anker1 == NULL) || (anker2 == NULL))
return(0);
p11 = anker1;
p21 = anker2;
p12 = p11;
p22 = p21;
do
{
p11 = p12;
p21 = p22;
p12 = (*p11).next;
p22 = (*p21).next;
if ((p12 != NULL) && (p22 != NULL))
{
fprintf(fp,"triangle{<%.2f,%.2f,%.2f><%.2f,%.2f,%.2f><%.2f,%.2f,%.2f>\n",(*p11).x,(*p11).y,(*p11).z,(*p12).x,(*p12).y,(*p12).z,(*p21).x,(*p21).y,(*p21).z);
fprintf(fp,"pigment{te}}\n");
fprintf(fp,"triangle{<%.2f,%.2f,%.2f><%.2f,%.2f,%.2f><%.2f,%.2f,%.2f>\n",(*p21).x,(*p21).y,(*p21).z,(*p12).x,(*p12).y,(*p12).z,(*p22).x,(*p22).y,(*p22).z);
fprintf(fp,"pigment{te}}\n");
}
}
while((p12 != NULL) && (p22 != NULL));
return(0);
} /* writepovtriangles */
/********************************************/
/* writerplline: */
/********************************************/
int writerplline(FILE *fp,struct punkt *anker1)
{
struct punkt *p11, *p12;
if (anker1 == NULL)
return(0);
p11 = anker1;
p12 = p11;
countw++; /* calc number of lines created */
fprintf(fp,"%.3f %.3f %.3f\n",(*p11).x/100.0,(*p11).y/100.0,(*p11).z/100.0);
do
{
p11 = p12;
p12 = (*p11).next;
if (p12 != NULL)
{
fprintf(fp,"%.3f %.3f %.3f\n",(*p12).x/100.0,(*p12).y/100.0,(*p12).z/100.0);
}
}
while(p12 != NULL);
return(0);
} /* writerplline */
/********************************************/
/* writerplfinish: */
/* */
/********************************************/
void writerplfinish(FILE *fp)
{
fprintf(fp,"%d\n",counth); /* height width of the mesh */
fprintf(fp,"%d\n",countw);
fprintf(fp,"3\n0\n255 255 255 0\n"); /* RGBA */
fprintf(fp,"\"Shell\"\n0\n"); /* Name */
fprintf(fp,"\"CEND\"\n");
fprintf(fp,"C_MESH DROP\n");
} /* writerplfinish */
/********************************************/
/* writet3dheader: */
/* */
/********************************************/
void writet3dheader(FILE *fp)
{
char percent = '%';
fprintf(fp," %c T3Dlib-data-file generated by Shelly1.2\n",percent);
fprintf(fp," %c the ShellShapeGenerator by RANDi : \n",percent);
fprintf(fp," %c (rschultz@informatik.uni-rostock.de)\n",percent);
fprintf(fp,"OBJ Begin \"Hierarchy 1\"\n");
fprintf(fp," DESC Begin \"Object 1 at level 1 of hierarchy 1\"\n");
fprintf(fp," NAME \"SHELL\"\n");
fprintf(fp," SHAP Shape = 2\n");
fprintf(fp," SHAP Lamp = 0\n");
fprintf(fp," POSI X=0 Y=0 Z=0\n");
fprintf(fp," AXIS XAxis X=1 Y=0 Z=0\n");
fprintf(fp," AXIS YAxis X=0 Y=1 Z=0\n");
fprintf(fp," AXIS ZAxis X=0 Y=0 Z=1\n");
fprintf(fp," SIZE X=32 Y=32 Z=32\n");
} /* writet3dheader */
/********************************************/
/* writet3dline: */
/********************************************/
int writet3dline(FILE *fp,struct punkt *anker1)
{
struct punkt *p11, *p12;
static int called = 0, count = 0;
if (anker1 == NULL)
return(0);
if(called == 0)
{
fprintf(fp," PNTS PCount %d\n",countp);
called = 1;
count =-1;
countw = 0;
}
countw++;
p11 = anker1;
p12 = p11;
fprintf(fp," PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n",++count,(*p11).x,(*p11).y,(*p11).z);
do
{
p11 = p12;
p12 = (*p11).next;
if (p12 != NULL)
{
fprintf(fp," PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n",++count,(*p12).x,(*p12).y,(*p12).z);
}
}
while(p12 != NULL);
return(0);
} /* writet3dline */
/********************************************/
/* writet3dfinish: */
/* */
/********************************************/
void writet3dfinish(FILE *fp)
{
int edges=0, faces=0, edgecount=0, facecount=0, a=0, b=0, r=0, r2=0, r3=0;
int point1=0, point2=0, edge1=0, edge2=0, edge3=0;
fprintf(stderr,"Writing additional T3Dlib-Data ...\n");
edges = (counth*(countw-1)+countw*(counth-1)+(counth-1)*(countw-1));
/* number of edges! */
fprintf(fp," EDGE ECount %d\n",edges);
/* write horizontal edges */
for (a=0; a<counth;a++)
{
r = a;
for (b=0;b<(countw-1);b++)
{
point1=r;
point2=r+counth;
fprintf(fp," EDGE Edge[%d] %d %d\n",edgecount++,point1,point2);
r=r+counth;
}
}
/* write vertical edges */
for (a=0; a<countw;a++)
{
r = a*counth;
for(b=0; b<(counth-1);b++)
{
point1=r+b;
point2=r+b+1;
fprintf(fp," EDGE Edge[%d] %d %d\n",edgecount++,point1,point2);
}
}
/* write diagonal edges */
for (a=0; a<counth-1;a++)
{
r = a;
for (b=0;b<(countw-1);b++)
{
point1=r;
point2=r+counth+1;
fprintf(fp," EDGE Edge[%d] %d %d\n",edgecount++,point1,point2);
r=r+counth;
}
}
/* ohhh boy, THIS (^^^) took me time ! :), now to that faces! */
/* write faces */
faces = 2*(countw-1)*(counth-1);
fprintf(fp," FACE TCount %d\n",faces);
r = 0;
r3 = countw*(counth-1)+counth*(countw-1);
for(a=0; a<counth-1; a++)
{
r2=counth*(countw-1)+a;
for(b=0; b<countw-1; b++)
{
edge1 = r+countw-1;
edge2 = r2;
edge3 = r3;
fprintf(fp," FACE Connect[%d] %d %d %d\n",facecount++,edge1,edge2,edge3);
edge1 = r;
edge2 = r2+counth-1;
edge3 = r3;
fprintf(fp," FACE Connect[%d] %d %d %d\n",facecount++,edge1,edge2,edge3);
r++;
r2=r2+counth-1;
r3++;
}
}
fprintf(fp," COLR R=98 G=68 B=58\n");
fprintf(fp," REFL R=0 G=0 B=0\n");
fprintf(fp," TRAN R=0 G=0 B=0\n");
fprintf(fp," SPC1 R=0 G=0 B=0\n");
fprintf(fp," End DESC \"Object 1 at level 1 of hierarchy 1\"\n");
fprintf(fp," TOBJ \"Object 0 at level 1 of hierarchy 1\"\n");
fprintf(fp,"End OBJ \"Hierarchy 1\"\n");
} /* writet3dfinish */
/**********************************************/
/* CalcCameraposition: */
/* */
/**********************************************/
void CalcCameraposition(struct ShellyArguments *ShellyArgs)
{
double x,y,z,R,S,O;
double my, Re, P, W1, W2, N, L, g, k;
double smin, smax, sd, a, b, A, beta, phi, omega, alpha, omin, omax, od;
double max = 0.0;
smin = (*ShellyArgs).smin*pi/180;
smax = (*ShellyArgs).smax*pi/180;
omin = (*ShellyArgs).omin*pi/180;
omax = (*ShellyArgs).omax*pi/180;
sd = (*ShellyArgs).sd*pi/180;
od = (*ShellyArgs).od*pi/180;
alpha = (*ShellyArgs).alpha*pi/180;
beta = (*ShellyArgs).beta*pi/180;
phi = (*ShellyArgs).phi*pi/180;
omega = (*ShellyArgs).omega*pi/180;
my = (*ShellyArgs).my*pi/180;
a = (*ShellyArgs).a;
b = (*ShellyArgs).b;
A = (*ShellyArgs).A;
N = (*ShellyArgs).N;
W1 = (*ShellyArgs).W1*pi/180;
W2 = (*ShellyArgs).W2*pi/180;
P = (*ShellyArgs).P*pi/180;
L = (*ShellyArgs).L;
fprintf(stderr,"Calculating Cameraposition ...");
fflush(stderr);
for(O = omin; (O+od)<omax; O=O+od)
{
for(S = smin; (S+sd)<smax; S=S+sd)
{
if (N == 0)
g = 0;
else
g = (2*pi)/N*(O*N/(2*pi)-round(O*N/(2*pi)));
Re = pow((pow(a,-2.0)*(cos(S)*cos(S))+pow(b,-2.0)*(sin(S)*sin(S))),-0.5);
if (N == 0)
k = L*exp(-(2*(S-P)/W1)*(2*(S-P)/W1));
else
k = L*exp(-1*(2*(S-P)/W1)*(2*(S-P)/W1))*exp(-1*(2*g/W2)*(2*g/W2));
R = Re + k;
x = (A*sin(beta)*cos(O)+R*cos(S+phi)*cos(O+omega)-R*sin(my)*sin(S+phi)*sin(O))*exp(O*cot(alpha));
y = (-1*A*sin(beta)*sin(O)-R*cos(S+phi)*sin(O+omega)-R*sin(my)*sin(S+phi)*cos(O))*exp(O*cot(alpha));
z = (-1*A*cos(beta)+R*sin(S+phi)*cos(my))*exp(O*cot(alpha));
countp++;
if (fabs(y)>fabs(z))
{
if (fabs(x)>fabs(y))
{
if(max<fabs(x))
max = fabs(x);
}
else
{
if(max<fabs(y))
max = fabs(y);
}
}
else
if (fabs(x)>fabs(z))
{
if(max<fabs(x))
max = fabs(x);
}
else
{
if(max<fabs(z))
max = fabs(z);
}
} /* for */
} /* for */
camy = 1.5*max;
camz = camy;
fprintf(stderr,"\n"); /* rrrrready :) */
} /* CalcCameraposition */
/**********************************************/
/* RenderShell: */
/* SSIA :) */
/**********************************************/
void RenderShell(struct ShellyArguments *ShellyArgs,char *fout)
{
struct punkt *List1anker, *List2anker, *L1p1, *L2p1, *L1p2, *L2p2;
double x,y,z,R,S,O;
double my, Re, P, W1, W2, N, L, g, k;
double smin, smax, sd, a, b, A, beta, phi, omega, alpha, omin, omax, od;
FILE *fp;
smin = (*ShellyArgs).smin*pi/180;
smax = (*ShellyArgs).smax*pi/180;
omin = (*ShellyArgs).omin*pi/180;
omax = (*ShellyArgs).omax*pi/180;
sd = (*ShellyArgs).sd*pi/180;
od = (*ShellyArgs).od*pi/180;
alpha = (*ShellyArgs).alpha*pi/180;
beta = (*ShellyArgs).beta*pi/180;
phi = (*ShellyArgs).phi*pi/180;
omega = (*ShellyArgs).omega*pi/180;
my = (*ShellyArgs).my*pi/180;
a = (*ShellyArgs).a;
b = (*ShellyArgs).b;
A = (*ShellyArgs).A;
N = (*ShellyArgs).N;
W1 = (*ShellyArgs).W1*pi/180;
W2 = (*ShellyArgs).W2*pi/180;
P = (*ShellyArgs).P*pi/180;
L = (*ShellyArgs).L;
if ((*ShellyArgs).output != RPL)
CalcCameraposition(ShellyArgs);
fp = fopen(fout,"w");
if (fp != NULL)
{
if ((*ShellyArgs).output == POV)
writepovheader(fp);
if ((*ShellyArgs).output == T3D)
writet3dheader(fp);
fprintf(stderr,"Calculating the Shell ...\n");
for(S = smin;(S+sd)<smax;S=S+sd)
{
if (N == 0)
g = 0;
else
g = (2*pi)/N*(O*N/(2*pi)-round(O*N/(2*pi)));
Re = pow((pow(a,-2.0)*(cos(S)*cos(S))+pow(b,-2.0)*(sin(S)*sin(S))),-0.5);
if (N == 0)
k = L*exp(-(2*(S-P)/W1)*(2*(S-P)/W1));
else
k = L*exp(-(2*(S-P)/W1)*(2*(S-P)/W1))*exp(-(2*g/W2)*(2*g/W2));
R = Re + k;
/* alternatively: */
/* R = pow((pow(a,2.0)*pow(cos(S),2.0)+pow(b,2.0)*pow(sin(S),2.0)),0.5); */
x = (A*sin(beta)*cos(O)+R*cos(S+phi)*cos(O+omega)-R*sin(my)*sin(S+phi)*sin(O))*exp(O*cot(alpha));
y = (-1*A*sin(beta)*sin(O)-R*cos(S+phi)*sin(O+omega)-R*sin(my)*sin(S+phi)*cos(O))*exp(O*cot(alpha));
z = (-1*A*cos(beta)+R*sin(S+phi)*cos(my))*exp(O*cot(alpha));
if ((L1p1 = calloc(1,sizeof(struct punkt))) == NULL)
{
fprintf(stderr,"Shelly: NOT ENOUGH MEMORY!!! ... exiting ... !\n");
fclose(fp);
myfree(List2anker);
myfree(List1anker);
exit(5);
} /* if */
if (S == smin)
List1anker = L1p1;
else
(*L1p2).next = L1p1;
L1p2 = L1p1;
(*L1p1).x = x;
(*L1p1).y = y;
(*L1p1).z = z;
} /* for */
if ((*ShellyArgs).output == RPL)
writerplline(fp,List1anker);
if ((*ShellyArgs).output == T3D)
writet3dline(fp,List1anker);
for(O = omin+od;(O+od)<omax;O=O+od)
{
counth = 0;
for(S = smin;(S+sd)<smax;S=S+sd)
{
counth++; /* calc number of points per line */
if (N == 0)
g = 0;
else
g = (2*pi)/N*(O*N/(2*pi)-round(O*N/(2*pi)));
Re = pow((pow(a,-2.0)*(cos(S)*cos(S))+pow(b,-2.0)*(sin(S)*sin(S))),-0.5);
if (N == 0)
k = L*exp(-(2*(S-P)/W1)*(2*(S-P)/W1));
else
k = L*exp(-1*(2*(S-P)/W1)*(2*(S-P)/W1))*exp(-1*(2*g/W2)*(2*g/W2));
R = Re + k;
/* alternatively: */
/* R = pow((pow(a,2.0)*pow(cos(S),2.0)+pow(b,2.0)*pow(sin(S),2.0)),0.5); */
x = (A*sin(beta)*cos(O)+R*cos(S+phi)*cos(O+omega)-R*sin(my)*sin(S+phi)*sin(O))*exp(O*cot(alpha));
y = (-1*A*sin(beta)*sin(O)-R*cos(S+phi)*sin(O+omega)-R*sin(my)*sin(S+phi)*cos(O))*exp(O*cot(alpha));
z = (-1*A*cos(beta)+R*sin(S+phi)*cos(my))*exp(O*cot(alpha));
if ((L2p1 = calloc(1,sizeof(struct punkt))) == NULL)
{
fprintf(stderr,"Shelly: NOT ENOUGH MEMORY!!! ... exiting ... !\n");
fclose(fp);
myfree(List1anker);
myfree(List1anker);
exit(5);
} /* if */
if (S == smin)
List2anker = L2p1;
else
(*L2p2).next = L2p1;
L2p2 = L2p1;
(*L2p1).x = x;
(*L2p1).y = y;
(*L2p1).z = z;
} /* for */
if ((*ShellyArgs).output == POV)
writepovtriangles(fp,List1anker,List2anker);
if ((*ShellyArgs).output == T3D)
writet3dline(fp,List2anker);
if ((*ShellyArgs).output == RPL)
writerplline(fp,List2anker);
myfree(List1anker);
List1anker = List2anker;
} /* for */
if ((*ShellyArgs).output == RPL)
writerplfinish(fp);
if ((*ShellyArgs).output == T3D)
writet3dfinish(fp);
fprintf(stderr,"Ready!\n");
myfree(List1anker);
if (fclose(fp) != 0)
fprintf(stderr,"Error while closing file: %s!\n",fout);
}
else
fprintf(stderr,"Could not open outfile: %s!\n",fout);
} /* RenderShell */
/********************************************/
/*main: */
/********************************************/
int main(int ac,char **av)
{
struct ShellyArguments ShellyArgs;
fprintf(stderr,"ShellyV1.2, the ShellShapeGenerator by RANDi\n");
if (ac < 3)
{
fprintf(stderr,"wrong arguments!\nUSAGE:\n\n");
fprintf(stderr," 'shelly infilename outfilename'\n\n");
exit(0);
} /* if */
ReadInfile(&ShellyArgs,av[1]);
RenderShell(&ShellyArgs,av[2]);
exit(0);
}